package com.zzw.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zzw.bean.AiMedia;
import com.zzw.bean.Msg;
import com.zzw.service.AiMediaService;
import com.zzw.utils.MinioUtil;
import com.zzw.utils.RedisUtil;
import com.zzw.utils.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author 赵志伟
 * @version 1.0
 */
@SuppressWarnings({"all"})
@Controller
@RequestMapping("/ai")
public class AiController extends BaseController {
    private static final String SILICON_FLOW_API_URL = "https://api.siliconflow.cn/v1/images/generations";
    private static final String SILICON_FLOW_VIDEO_SUBMIT_URL = "https://api.siliconflow.cn/v1/video/submit";
    private static final String SILICON_FLOW_VIDEO_STATUS_URL = "https://api.siliconflow.cn/v1/video/status";

    private final RestTemplate restTemplate = new RestTemplate();

    private String apiKey = "sk-lzrwqeciftlrguedowbowyvypoweaackekunxucnpcjakleh";

    /*
    关于 ${media.upload.path:/upload/media} 的解释
    这个表达式是Spring框架中的属性占位符（Property Placeholder）语法，它有一个特殊的格式：${property.name:default_value}。
    详细解释：
    属性占位符：${media.upload.path} 部分表示Spring会在配置的属性文件中查找名为 media.upload.path 的属性。
    默认值：冒号后面的 /upload/media 是一个默认值。这意味着：
    如果在属性文件（我们的media.properties）中找到了 media.upload.path 属性，则使用该属性的值
    如果没有找到该属性，则使用默认值 /upload/media
    应用场景：这种设计非常实用，因为它提供了一种优雅的回退机制。即使配置文件中没有定义特定属性，应用程序仍然可以使用合理的默认值继续运行。
     */
    // 媒体文件保存路径，从配置文件中读取
    @Value("${media.upload.path}")
    private String mediaUploadPath;

    @Autowired
    private AiMediaService aiMediaService;

    @Autowired
    private HttpServletRequest request;

    @PostMapping("/generate-image")
    @ResponseBody
    public Msg generateImage(@RequestBody Map<String, Object> request) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + apiKey);

            // 创建请求体
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(request, headers);

            // 发送请求
            ResponseEntity<Map> response = restTemplate.exchange(
                    SILICON_FLOW_API_URL,
                    HttpMethod.POST,
                    requestEntity,
                    Map.class
            );

            if (response.getStatusCode() == HttpStatus.OK) {
                // 保存图片信息到数据库
                Map<String, Object> imageData = response.getBody();
                if (imageData != null && imageData.containsKey("images")) {
                    List<Map<String, String>> images = (List<Map<String, String>>) imageData.get("images");
                    for (Map<String, String> image : images) {
                        String remoteUrl = image.get("url");
                        // 下载图片到minio
                        String localUrl = downloadMediaFile(remoteUrl, 1);

                        AiMedia aiMedia = new AiMedia();
                        aiMedia.setMediaType(1); // 1-图片
                        aiMedia.setMediaUrl(localUrl); // 使用本地URL
                        aiMedia.setRemoteUrl(remoteUrl); // 保存原始远程URL
                        aiMedia.setPrompt((String) request.get("prompt"));
                        aiMedia.setMediaSize((String) request.get("image_size"));
                        aiMedia.setModel((String) request.get("model"));
                        aiMedia.setStatus(1); // 1-成功
                        aiMediaService.saveAiMedia(aiMedia);

                        // 替换返回结果中的URL为本地URL
                        image.put("url", localUrl);
                    }
                }

                return Msg.success().add("image", response.getBody());
            } else {
                return Msg.fail("图片生成失败");
            }
        } catch (Exception e) {
            return Msg.fail(e.getMessage());
        }
    }

    @PostMapping("/generate-video")
    @ResponseBody
    public Msg generateVideo(@RequestBody Map<String, Object> request) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + apiKey);

            // 创建请求体
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(request, headers);

            // 发送视频生成请求
            ResponseEntity<Map> response = restTemplate.exchange(
                    SILICON_FLOW_VIDEO_SUBMIT_URL,
                    HttpMethod.POST,
                    requestEntity,
                    Map.class
            );

            if (response.getStatusCode() == HttpStatus.OK) {
                String requestId = (String) response.getBody().get("requestId");

                // 保存视频信息到数据库
                AiMedia aiMedia = new AiMedia();
                aiMedia.setMediaType(2); // 2-视频
                aiMedia.setPrompt((String) request.get("prompt"));
                aiMedia.setMediaSize((String) request.get("video_size"));
                aiMedia.setModel((String) request.get("model"));
                aiMedia.setRequestId(requestId);
                aiMedia.setStatus(0); // 0-处理中
                aiMediaService.saveAiMedia(aiMedia);

                return Msg.success().add("requestId", requestId);
            } else {
                return Msg.fail("视频生成请求失败");
            }
        } catch (Exception e) {
            return Msg.fail(e.getMessage());
        }
    }

    @PostMapping("/check-video-status")
    @ResponseBody
    public Msg checkVideoStatus(@RequestBody Map<String, String> request) {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Authorization", "Bearer " + apiKey);

            HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(request, headers);

            ResponseEntity<Map> response = restTemplate.exchange(
                    SILICON_FLOW_VIDEO_STATUS_URL,
                    HttpMethod.POST,
                    requestEntity,
                    Map.class
            );

            if (response.getStatusCode() == HttpStatus.OK) {
                Map<String, Object> statusData = response.getBody();
                String requestId = request.get("requestId");

                // 如果视频生成成功，更新数据库记录
                if (statusData != null && "Succeed".equals(statusData.get("status"))) {
                    Map<String, Object> results = (Map<String, Object>) statusData.get("results");
                    if (results != null && results.containsKey("videos")) {
                        List<Map<String, String>> videos = (List<Map<String, String>>) results.get("videos");
                        if (videos != null && !videos.isEmpty()) {
                            String remoteUrl = videos.get(0).get("url");

                            // 下载视频到本地
                            String localUrl = downloadMediaFile(remoteUrl, 2);

                            // 更新数据库中的视频URL和状态
                            AiMedia aiMedia = aiMediaService.getAiMediaByRequestId(requestId);
                            if (aiMedia != null) {
                                aiMedia.setMediaUrl(localUrl); // 使用本地URL
                                aiMedia.setRemoteUrl(remoteUrl); // 保存原始远程URL
                                aiMedia.setStatus(1); // 1-成功
                                aiMediaService.updateAiMedia(aiMedia);
                            }

                            // 替换返回结果中的URL为本地URL
                            videos.get(0).put("url", localUrl);
                        }
                    }
                } else if (statusData != null && !"InProgress".equals(statusData.get("status"))) {
                    // 如果视频生成失败，更新状态
                    AiMedia aiMedia = aiMediaService.getAiMediaByRequestId(requestId);
                    if (aiMedia != null) {
                        aiMedia.setStatus(2); // 2-失败
                        aiMedia.setRemark((String) statusData.get("reason"));
                        aiMediaService.updateAiMedia(aiMedia);
                    }
                }

                return Msg.success().add("status", response.getBody());
            } else {
                return Msg.fail("获取视频状态失败");
            }
        } catch (Exception e) {
            return Msg.fail(e.getMessage());
        }
    }

    /**
     * 下载媒体文件到本地服务器
     *
     * @param remoteUrl 远程URL
     * @param mediaType 媒体类型：1-图片，2-视频
     * @return 本地访问URL
     */
    private String downloadMediaFile(String remoteUrl, int mediaType) throws IOException {
        HttpServletRequest request = WebUtils.servletRequest.get();
        String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());

        // 生成文件名
        String fileExtension = mediaType == 1 ? ".png" : ".mp4";
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + fileExtension;
        String filePath = mediaUploadPath + dateDir + fileName;

        String minioPath = MinioUtil.uploadByUrl(remoteUrl, MinioUtil.MINIO_BUCKET_NAME, filePath);

        return minioPath;

        //// 创建保存目录
        //// 获取项目的根路径 /E:/idea_project/zzw_ssm/furn-ssm-easyui/target/furn-ssm-easyui-1.0-SNAPSHOT/
        //// 获取项目的class路径, 用于存放生成的文件 /E:/idea_project/zzw_ssm/furn-ssm-easyui/target/furn-ssm-easyui-1.0-SNAPSHOT/WEB-INF/classes/
        //HttpServletRequest request = WebUtils.servletRequest.get();
        ////String realPath = request.getServletContext().getRealPath("/");
        //String classPath = ResourceUtils.getURL("classpath:").getPath();
        //String destPath = new File(classPath).getParentFile().getAbsolutePath() + "/static/";
        //String dateDir = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
        //
        //String sourceFilePath = destPath + WebUtils.UPLOAD_AI_DIR + dateDir;
        //
        //File folder = new File(sourceFilePath);
        //// 检查文件夹是否存在，不存在则创建
        //if (!folder.exists()) {
        //    folder.mkdirs();
        //}
        //
        //// 生成文件名
        //String fileExtension = mediaType == 1 ? ".png" : ".mp4";
        //String fileName = UUID.randomUUID().toString().replaceAll("-", "") + fileExtension;
        //String filePath = sourceFilePath + "/" + fileName;
        //
        //// 下载文件
        //try (InputStream in = new URL(remoteUrl).openStream();
        //     FileOutputStream out = new FileOutputStream(filePath)) {
        //    byte[] buffer = new byte[4096];
        //    int bytesRead;
        //    while ((bytesRead = in.read(buffer)) != -1) {
        //        out.write(buffer, 0, bytesRead);
        //    }
        //}
        //
        //// 检查文件是否成功保存
        //File savedFile = new File(filePath);
        //System.out.println("文件是否存在: " + savedFile.exists() + ", 文件大小: " + savedFile.length() + " 字节");
        //
        //// 构建正确的访问URL（确保格式正确）
        //String localUrl = request.getContextPath() + "/static/" + WebUtils.UPLOAD_AI_DIR + dateDir + "/" + fileName;
        //
        //System.out.println("远程URL: " + remoteUrl);
        //System.out.println("本地文件路径: " + filePath);
        //System.out.println("本地访问URL: " + localUrl);

        //return localUrl;
    }

    @RequestMapping("/media/list")
    @ResponseBody
    public Msg getAiMediaList(AiMedia aiMedia,
                            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
                            @RequestParam(value = "sort", defaultValue = "") String sort,
                            @RequestParam(value = "order", defaultValue = "") String order) {

        PageHelper.startPage(pageNum, pageSize, WebUtils.getOrderBy(sort, order));
        List<AiMedia> list = aiMediaService.getAiMediaList(aiMedia);
        PageInfo<AiMedia> pageInfo = new PageInfo<>(list, pageSize);
        return Msg.success().add("pageInfo", pageInfo);
    }

    /**
     * 删除单个AI媒体记录
     * @param id 媒体ID
     * @return 处理结果
     */
    @PostMapping("/media/delete")
    @ResponseBody
    public Msg deleteAiMedia(@RequestParam("id") Integer id) {
        try {
            // 先获取媒体信息，用于删除文件
            AiMedia aiMedia = aiMediaService.getAiMediaById(id);
            if (aiMedia != null && aiMedia.getMediaUrl() != null) {
                // 删除物理文件
                deleteMediaFile(aiMedia.getMediaUrl());
            }

            // 删除数据库记录
            int result = aiMediaService.deleteAiMediaById(id);
            if (result > 0) {
                return Msg.success();
            } else {
                return Msg.fail("删除失败");
            }
        } catch (Exception e) {
            return Msg.fail(e.getMessage());
        }
    }

    /**
     * 批量删除AI媒体记录
     * @param ids ID数组
     * @return 处理结果
     */
    @PostMapping("/media/batchDelete")
    @ResponseBody
    public Msg batchDeleteAiMedia(@RequestParam("ids[]") Integer[] ids) {
        try {
            // 先获取所有媒体信息，用于删除文件
            for (Integer id : ids) {
                AiMedia aiMedia = aiMediaService.getAiMediaById(id);
                if (aiMedia != null && aiMedia.getMediaUrl() != null) {
                    // 删除物理文件
                    deleteMediaFile(aiMedia.getMediaUrl());
                }
            }

            // 批量删除数据库记录
            int result = aiMediaService.batchDeleteAiMedia(ids);
            if (result > 0) {
                return Msg.success();
            } else {
                return Msg.fail("批量删除失败");
            }
        } catch (Exception e) {
            return Msg.fail(e.getMessage());
        }
    }

    /**
     * 删除媒体文件
     * @param mediaUrl 媒体URL
     */
    private void deleteMediaFile(String mediaUrl) {
        try {
            if (mediaUrl != null && !mediaUrl.isEmpty()) {
                // 获取项目的根路径
                String realPath = request.getServletContext().getRealPath("/");
                // 从URL中提取相对路径
                String relativePath = mediaUrl;
                if (mediaUrl.startsWith(request.getContextPath())) {
                    relativePath = mediaUrl.substring(request.getContextPath().length());
                }

                // 构建完整的文件路径
                String filePath = realPath + relativePath;

                // 删除文件
                File file = new File(filePath);
                if (file.exists() && file.isFile()) {
                    file.delete();
                    System.out.println("已删除文件: " + filePath);
                }
            }
        } catch (Exception e) {
            System.err.println("删除文件失败: " + e.getMessage());
        }
    }

    @RequestMapping("/test-media-access")
    @ResponseBody
    public Msg testMediaAccess() {
        try {
            // 获取上传目录的绝对路径
            String realPath = request.getServletContext().getRealPath("/");
            String uploadDir = realPath + mediaUploadPath;

            // 检查目录是否存在
            File dir = new File(uploadDir);
            boolean dirExists = dir.exists();

            // 列出目录中的文件
            String[] fileList = dir.exists() ? dir.list() : new String[0];

            // 返回目录信息
            return Msg.success()
                    .add("realPath", realPath)
                    .add("uploadDir", uploadDir)
                    .add("dirExists", dirExists)
                    .add("fileList", fileList)
                    .add("mediaUploadPath", mediaUploadPath);
                    //.add("mediaAccessUrlPrefix", mediaAccessUrlPrefix);
        } catch (Exception e) {
            return Msg.fail(e.getMessage());
        }
    }

    @RequestMapping("/test-media")
    public String testMediaPage() {
        return "ai/test-media";
    }
}
